Log In  
[back to top]

[ :: Read More :: ]

Cart #wip_ma_20200905-0 | 2020-09-05 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
5

Just in time for GBJAM8.
I had to remove the breakable pots to conserve tokens.
I am literally at 8192 tokens even after making even more optimizations!
I had to add the key and door to exit the stage.

P#81517 2020-09-05 11:31

[ :: Read More :: ]

Cart #wip_ma_20200902-2 | 2020-09-03 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
5

Hey again. Goober here.

This revision has me REALLY looking in every little nook and cranny I can find
to get precious tokens. I've had to resort to utilizing SECRET SPECIAL tricks
to making sure I can load as much data as possible while not using very many
tokens at all. In the beginning of my code I've created a special function:

-- handy token-saving function
glb     =_𝘦𝘯𝘷
function vars(...)
    local a={...}
    local b=split(a[1],",")
    local c=2
    for i in all(b) do
        glb[i]=a[c]
        c+=1
    end
end

Pair this with one of my modules - the dialog module, for example:

vars("dlg_active,dlg_id,dlg_port,dlg_snd,dlg_tpos1,dlg_tpos2,dlg_text1,dlg_text2,dlg_next,dlg_pside,dlg_cblnk,dlg_done",
false,nil,0,
0,0,0,
"","",0,
left,0,0
)

This will allow me to assign multiple global variables while saving about 1/3
of the tokens. A lot of data is being converted to strings in order to save
more and more tokens. Data which doesn't need to be written to very often
may also be stored together in strings, but I haven't really gotten to that
point yet.

What will PROBABLY happen is that I'll start looking into using peek/poke
for reading and writing data. One of the problems with using poke, though, is
that each call to this is 4 tokens. [poke ( offset , value]. The ending brace
doesn't count. Peeking is about the same. Even with shorthand peeking, it takes
four tokens to assign a value.

But, there are some features added to this version!

  • When attacking and killing bats, their spheara (currency is souls) is sucked
    in by the magic lantern. When the lantern takes the soul, it glows bright for
    a split second.

  • It's now possible to die. While it's not possible to be hurt by the bats
    right now (fixed this), you can die from spikes or falling into the water at the bottom of
    the stage. This results in a neat effect! Also, when you die, a password is
    displayed. While this password doesn't serve any purpose right now, I'm planning
    on allowing players to input their password upon startup.

  • You still can't end the level yet. The key actor has not yet been implemented.
    Because I'm out of tokens right now, I'll need to save some more before I can
    implement this. It's in the works!

I think that's it for now. See ya!

~ Goober

P#81473 2020-09-03 11:04 ( Edited 2020-09-03 12:05)

[ :: Read More :: ]

Cart #wip_ma_20200831-0 | 2020-08-31 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4


Hey again. Goober here.

I've made some impressive changes to the cart! Here's some of the neat things
I added:

  • You can attack and kill the bats and pots in the level! For now they both
    add 10 to your score. It also makes this neat little explosion when you
    defeat them, with a cool sound effect.

  • The magic lantern in the cutscene now shows up in gameplay! This lantern
    is the basis of storing your currency, which is called Spheara. It glows
    faintly as it travels with you. The spirit of the hero's brother Coji also
    resides in this lantern.

  • You still can't die, but I'm working on it. If you're on the bottom level of
    the map and you fall through the water below, you'll have to reset.

  • There's still some oddities with the map looping and actors not really
    behaving like it's a seamless loop, but at least the foreground and background
    map tiles do!

  • The map was simplified to make it easier to build levels via 8x8 chunks.
    This does limit the amoutn of variety for now, but it's a fine placeholder
    for building as many maps as I would like.

  • While not implemented, there exists a password system hidden in the game's
    code which will be utilized at some point later in development.

Again, I'm topped off on tokens, which means I'm gonna have to find ways to
save some somewhere.

Tokens: 8190 / 8192
Characters: 43954 / 65535
Compression: 90%

Believe it or not, compression was actually hassling me too. I lessened this
by replacing the detailed map from a prior version to a chunk-based one. The
string size is MUCH less than the former.

While adding stages is absolutely no hassle at all (really only adds a handful
of tokens each level (like.. 9?) adding content for the game is proving to be
very difficult. I don't want to remove anything that is currently in place,
and I'm already scrubbing every nook and cranny I can find for any amount of
tokens I can save. I still have a lot I need to do as well:

  • Implement the other 4 abilities (Water, Ice, Lightning, Wind Magic)
  • Make it so Makeii can get hurt and die, and also get a game over.
  • Implement charged up abilities
  • Utilize an ability-changing menu when holding down and Z
  • Make a shield appear when Makeii is holding down and X.
  • Implement more enemies so I can make use of the sprites I made for them.
  • Implement key + locked door mechanic so you can leave the level.

I really REALLY wish that we had the ability to test games even if they go
over the token/char limit. While it is possible to still test carts over the
compression rate of 100%, it would be much easier to first implement all
of the content I need to and then compress and optimize whatever I can. I may
need to resort to a minifier to get everything to fit in there. Identifiers
which are substituting for numbers could probably be optimized that way.

That's all for now!

P#81391 2020-08-31 08:19

[ :: Read More :: ]

So I was thinking about how charming it would be to make a password system for my current game in progress, but I'm not entirely sure where to start on it.

I guess the first thing I would need to do is determine which values need to be saved to the password, determine the ranges in which these values are valid, determine the base for each character in the password, and then encrypt the password which displays to the player when they want to quit the game.

Let me make a small hypothetical data set that needs to be saved in the password:

HP-LV  (min 0, max 6, 3 bits)
MP-LV  (min 0, max 6, 3 bits)
SCORE  (min 0, max 99999999, saves in multiples of 100, so real range is 0-999999, which means 20 bits)
STAGE  (min 0, max 7, 3 bits - stage saves as 0-7)
INV.   (bitfield of 10 items, 15 bits (5 items have level-2 upgrades, one bit each))

TOTAL: 44 bits (move this up to 48 to increase non-possible pw combos)
HHH MMM SSSSSSSSSSSSSSSSSSSS TTT IIIIIIIIIIIIIII 0000

Possible PW Character Set (base 32):
ABCDE FGHIJ KLMNO PQRST UVWXY Z1234 56

48 bits / 6 bits per character = password length of 8.

Possible password attempt:
QQQQQQQQ (Solar Jetman fans, word up!)
Q=16

per character:
010000 010000 010000 010000 010000 010000 010000 010000

per assignment
HHH MMM SSSSSSSSSSSSSSSSSSSS TTT I2I2I2I2I2IIIII 0000
010 000 01000001000001000001 000 001000001000001 0000

This equates to:
HP-MAX Lv.2
MP-MAX Lv.0
SCORE: 266305+00
STAGE: 0
INV.:  2 items obtained (level 0), 1 passive item
ERR BITS: 0 (pass)

So, I need to figure out how to encrypt this password to be harder to interpret, as well as utilize the error bits at the end to further keep players from typing in random passwords and getting "cheat passwords". Any ideas on how I can go about this?

P#81281 2020-08-28 05:07

[ :: Read More :: ]

Cart #wip_ma_20200824-0 | 2020-08-25 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

-------------------------------------------------------------------------------
Well, this version definitely had me scraping every little inefficiency
I could think of to save tokens. There's still a lot that can be saved, but
right now I'm pretty much fighting against the token limit to try and add
more and more features.

Stats:
tokens: 7885 / 8192
chars: 48853 / 65535
compression: 97%

To start, I had to start doing variable recycling for scenes. Because the dot
operator counts as a token, it's more efficient to keep data on the global
namespace than to utilize containers. Because of this, scenes are using generic
variables like "sc_1" through "sc_7" at the moment. As a strangely positive
consequence, my game runs much more efficiently and uses a lot less CPU.

I was originally concerned about doing it this way, but it turns out that I
have a lot of RAM to spare. I think PICO-8 allows up to 2048 KB? The game's
debug stats seem to show that I'm only using 250 KB or something.

I'm watching my code sort of merge into a less elegant but more efficient style.
It's more efficient to use expressions than branches, but it's still good to
use functions instead of GOTO branching. as far as I know. It doesn't save any
tokens to GOTO branch if I recall.

Because comments affect the compression percentage of the cart, most of them
have been removed. I'm expecting the code to become less readable as time goes
on, but I'll have a good amount of knowledge about the code I've written for
each section.

Anyway, in this version, the first (non-killable) enemy is seen! There's bats
flying around the place now, but I have to fix the fact that they'll fly off 
the edge of the map because their position doesn't wrap around like the player's
does. If I set their solid flag to true, I can ride on them! It was turned off
in this version, however.

There is another actor that was made, but it's indistinguishable from the
foreground tiles it represents. I've added pots to the game, which eventually will
be breakable in order to get stuff like healing items and game currency. They
will respawn like enemies do when you change vertical layers, so it may be an
efficient way to farm things you will need.

You may also notice in this version that a very weird noise plays when you
step on spikes or lava. This was me testing harmful tiles while making sure
that they don't hurt the player if they're still standing on the ground. The
noise still plays when you're standing NEXT to spikes though, so I have to fix
that.

So far I haven't needed to sacrifice any of the content I've made for the game
so far. I've only needed to compress their information or made their modules
more efficient. I'll need to find clever ways to beat the token limit, which
is my current adversary in development. Maybe I can implement a tiny string
parser which can ease the load? It will cost CPU to add an interpreter on top
of an interpreter (Lua) but if it means saving valuable tokens, then I'll
start working on one.

Cheers!
- Goober
-------------------------------------------------------------------------------
P#81152 2020-08-25 06:39

[ :: Read More :: ]

Cart #wip_ma_20200821-0 | 2020-08-21 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

Hey again.

Some new things in this update!

* Platforms work! It took a little bit of code to get them to work as expected,
  but now they function to impede downward motion for entities while encouraging
  non-opacity for upwards velocity. In short, they do what platforms do.

* While there's no enemies or hurtful terrain to worry about, there is a full
  four-layer stage to explore! Each stage will be somewhere around this size.
  I'm barely beneath the compression cap (which I didn't know was a thing until
  tonight) which will cause me to have some serious issues with optimizing
  short-term.

  Platforms use sprite flag 6, or [& 64]. The use of sprite flags have made it
  much easier to handle map collision data by associating the sprite IDs with
  these attributes. While there's only 8 flags to work with, they can be used
  as categories for further fine tuning with actual sprite IDs. Sprite flag 0
  always serves as solid collision detection on the map.

* Stage layers are decompressed (foreground and background) from a cheap and
  simple compression method which simply states [tile][amt] in hex. For example,
  the first stage layer starts off with "1204 b108" which means from the topleft
  of the stage area, it first places four tiles of ID of 18 (blank transparent).
  It then places adjacent to it eight tiles of 177 (bricks).

  This compression method, while simple, cuts the level data down to 1/3 of the
  usual size, mostly. If there's lots of the same tiles banded together
  horizontally, the compression method works extremely well. Stage 1-4's BG
  layer uses a gradient which makes it looks like this when compressed:
  "13388738883889388a388b388c70"
  This covers the entire 56 by 8 tiles of the background (16 by 8 tiles are
  not saved because the first and last 16x8 tiles for both the foreground and
  background are exactly the same to give the illusion of the looping mechanic).

* Current cart stats:
  8103/8192 tokens
  49955/65535 chars
  98% compressed size

  As you can see, I've pretty much hit the limit on both tokens and compressed
  size. I didn't think that I would need to worry so much about the third one,
  but it looks like even comments add to this percentage. I could very well
  be at the limit of the cart's virtual space and will need to look for some
  compression methods. This is the fun part! There are a lot of things which
  could be simplified.

* One thing I didn't think I would have is extra map space. I'm actually not
  using much of it at all. A lot of the space was going to be used for world
  slices and make maps out of those. It may be something to resort to in the
  future, though.

  I want to keep all the data on a single cart and not feel like I need to load
  anything from an external file. However, should I need to utilize multiple
  carts for this game (kind of like multiple CDs for games back in the day),
  it may be an option.

That's all for now!
- Goober
P#80999 2020-08-21 11:27

[ :: Read More :: ]

Cart #wip_ma_20200817-0 | 2020-08-18 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

Okay! Quite a few changes in this version.

You can walk the player around on a flat solid terrain (the world collision
isn't put in yet so the only solid tiles are the ones on the very bottom). I
made sure to make the movement of the player feel smooth when jumping, yet
tight when walking left or right. It kind of works like Megaman a little bit.

Pressing Z will jump, and pressing X will attack with a little magic slice.
The player, who's name is Makeii, is a spellsword who has the ability to
change his weapon since it's made of mana. The game's weapon mechanics have
been simplified a lot (only one item slot on the top now). Holding down X will
charge Makeii up. When at full charge, he can spend an AP (the triangle meter)
to use the spell in his item slot. There aren't any spells coded in at the
moment, so all it does is reduce AP by one point.

Because there aren't a lot of buttons to use to map to things, ducking is
considered Makeii's defensive position. I'm planning to allow the two buttons
to activate a shield or to use defensive magic after charging, allowing
each spell to have two different uses. Still in the works.

I'm at 7488/8192 tokens, though. I'm going to have to find a way to compress
and save tokens as I build the game more, but the token cap isn't deterring me
from this goal. With each wip version, things get shifted around, more code
gets added, and code already added gets optimized to save tokens. It's expected
to hit and exceed the token cap in the near future, so cutting out some stuff
or making things a little more efficient will need to happen.

I found out that a pair of parenthesis counts as a single token () and
multiplying is also one token, so functions which do things like multiply
a variable by a number seems to be fine. For example, I'm using a function
called "TL(x)" which acts as a multiplier for a tile size, which all it does
is return (x*8). Three tokens for the definition of this function, and two
tokens everywhere else. I could instead use the literal pixel value, but I 
feel like that's going to happen during the late optimization phases.

Finally, comments don't add to the token count, only the char count. This is
good because a lot of variables have abbreviated names due to the small screen
space working with pico-8. I've already tripped up on some of my own variable
names which don't make a lot of sense without context.

Cheers!
- Goober
P#80901 2020-08-18 03:13 ( Edited 2020-08-18 04:59)

[ :: Read More :: ]

Cart #wip_ma_20200812-3 | 2020-08-13 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Howdy again.

Here to give you some updates on the game so far.

I've managed to save a fair amount of frames by not worrying so much about
keeping information in tables and moving data to the global namespace. What I
mean by this is instead of something like "nested.table.variables" instead
I go with "global_namespace_variable". Using the latter method will save
me lots of tokens. I've managed to add content and I'm actually lower than
my last count in the previous post (5931/8192).

The intro is pretty much done, so now all that's left is to work on gameplay.
Currently there's a test stage. You can't control the player just yet, but
it's next on my todo list. Instead you can pan the camera across the stage.

I was aiming for a huge overworld with a map you could check on, but I guess
instead I'll make it simple and keep the game stage-based, which should help
keep my token count within reason. Each stage can have multiple rooms of
varying length. I may even see about making the rooms loop horizontally, since
the game takes place in a tower.

The test area is currently manually mapped out just for visual purposes.
The parallax looks okay, except when moving slowly. In this test you can see
that I had some trouble lining up the building interior with the foreground,
but it really doesn't look all too good even if it is lined up right. I could
probably do some coding magic to alter the background tiles to interior, or
maybe I just won't be bothered to go to that extent.

Oh, also, there's a secret if you hang around long enough on the "MAGUS AORA"
title screen. :]
P#80709 2020-08-13 13:21 ( Edited 2020-08-13 13:36)

[ :: Read More :: ]

Cart #wip_ma_20200811-0 | 2020-08-11 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
3

-------------------------------------------------------------------------------
Some new things in this WIP since the previous version:

* Added compressed slide data and slide module. This can fill the playfield
  with a static slide. The slide data is kept as a hex string, so each char
  can hold two pixels (with values 0-3). The playfield is 112x64 pixels,
  meaning that each slide is 3584 characters long. Decompressing and drawing
  the slide once to the screen probably takes more than a whole tick, but I
  was expecting it to be a lot slower. Win win!

That looks like this, for no one asking:

aaaaaaaaaaaaaaaaa8255555556802aaaaaaaaaaaaaaaaaaaaaaaaaaa6a6a6a6a6a6a6a6a46aaaaa
56aa80a6a6a6a6a6a6a6a6a6a6a6a6a6aaaaaaaaaaaaaaaaa0aaa0029a00a82aaaaaaaaaaaaaaaaa
aaaaaaaa666666666666666661aa855498550c26666666666666666666666666a9a9a9a9a9a9a9a9
87aa1aa6a6695309a9a9a9a9a9a9a9a9a9a9a9a966666666666666660fea2aaaaaaaa4c266666666
666aaaa66666666699999999999999981ffc6aaaaaaaad30999999999aa000a99999999956565656
565656503ffcfe00902abf3c165656566801a42a5656565699999999999999807ff1ff28120fff4d
09999999a06809099999999955555555555555406ff3fcaa0283ffcfd15555556180020955555555
5959595959595900aff3f0aaa2a8ffd3a419595962008209595959595555555555555401aba3f2bf
fff8fff25055555562026309555555559595959500959406aaa7cbfffffe3ff401959595a30a6309
959500955555555408055406aa8a0c03fff00ffc555555556309830955540805555555400a80541a
90093cb0ffcb8ff855550055a30a0c29554002055555540002a0006941043c3cffc383f81554200a
8000382aa90002805555400000aa01500104bc3fffc390a805000a2a8555003aaa0000a055550000
002a00000000affffbff80a8800002aa2aaaa03eaa80002815400000000a80001406affffcfe40a8
400002bf03ffff3ffa800002000000000002a802a502affffffe00a4000002bf1000000ffa800000
000000000000a80aa401affffffa00240000aabc1afff94ffe800000000000000000280aa0002bfc
a3e904240000aafc6bf3fa43fea000000000000000000000000006ffffa414240000abfcaffcfe90
fea800000000000000000000000000bffaa0142400002bfcbff0ff90ffa800000000000000000000
5000181aaa40102400002afcafc03f90ffe80000000000000000004140001bc00000002400002afc
6bc03e90ffea0000000000000000014942016fffa480001000002afc1af0fa43ffaa800000000000
000004254800bfffa4aa001000002afc02bfe903feaa80000000000000002825080003ffe9280010
00000aa0b0000003feaa8000000000000000a8290800000000000a00000002802c0000c3faaa0000
000000000000aa940a02aabffaaaaa0000000a0002ffff03eaa80000000000000000aa400282abff
fffff8200000080e202aa802aa800000000000000000a50202802abfffffe820000008280b000202
aa000000000000000000802a002200abfc3aabe00000080002fff800a000000000000000000003ea
800fc00000aabf8200000803c0000030a00000000000000000000ffa8100ff002aaffe0280000aaa
c3003c20200000001000010050000ffe81500bffffffc00a80055402c383fc282800000015000001
50003fff8055002aa800000ea00000028e0faa02080000002955000000003fffa05550000001503f
a00000028a0aaaa02800aaa40aa900000000ffffe05555500055503fe80000008028002aa0005550
01a954000000ffffe05a95555469503ffa000000aaa00000000000000000000095403fffe05aa695
54aa543ffa002a9000000000000000000000000025400fffe06aaa9514aa583ffe00aa5000045500
000000000aaa5000000003ffe06aaa9404aaa80ffe80554000015000000000000aa56aa0000013ff
e85aaa9404aaaa0fff000000000000002aaa8000295aaaa90000243ff85aaa55542aba0fff000000
00000002aaaaa50015aaa5550000a90ff85aaa55552aaec3fc000012aaa000015555550000000000
0000e940005aa955052aefc0c0000016aa50000055500000000000001540ea540056a554012aefc0
0500000555000000000000006aaa90015500fa900056a950000aeff0290000000000140000000000
569550000000fa900056a950004afffc290014000000000000000000a55000000003fe800056a950
0003fffc3a4000000000000000005550550002a90003fe800055aa500013ffff0e8000000a800000
000055400000aaaaa003fe8000556a500010ffff0e80001aaaaaaa940000000000056aaa940ffa00
00156a540054ffff028000156aaaa55aa800000000005695540ffa0100055a5400542bffc2a00005
55555aaaaa80000000000555000ffa014001555555542babc3a000005555555555400000aaa00000
000ff8015000555555552baac3a800000555554000000000aaaa00000000f8000000055501540aaa
83fa01400000000000000000aaaa9400400800000008001020000aaa83f000000000000540000000
a5555500000aa0000140bc03e8038aaa8001000000000015400002a8555555000000950001540bcf
ea3802aa40a90000000000040000aaaa00000001002800000169400ffa0042a6429000008aa80000
002aaaa900000055402a940005aa9543e8554155000940015aaa80000aaaaaa5

* The code's been slightly overhauled in the backend. Some minor speed
  improvements and token saving. I'm really worried about hitting the max
  token amount because I'm already at 6020 / 8192. I'm nowhere near the
  character limit, so the slides mentioned above can hold lots of data while
  barely affecting the token limit.

* Attempts to keep things as modular as possible is saving me from duplicating
  a lot of code for no reason. There's always going to be exceptions, though.

* IF/ELSEIF/ELSE branches are slow when you use them frequently on every tick,
  so plans to swap those out for function references are in the works.

* Sorry for no actual gameplay. I plan to use cheap point-in-rect collision
  detection for whole-pixel movement and not worry so much about subpixel
  stuff. Velocities for actors will still retain floating point precision,
  but actors will "inch" pixel by pixel for the amount they need to move, and
  stop moving if they happen to collide with a world tile. It's simple and
  effective when moving small distances. Since the screen's resolution is
  already pretty small, and things won't move faster than 2-4 pixels at a
  time, I believe this is a great route to take.

* I want to maintain a constant 60 FPS throughout the whole experience, so
  there are going to be some corners I'll need to cut later on. The HTML5
  version chugs pretty bad on my Android device when I'm using per-pixel
  shading (the diamond effect, additive strips on the main menu and intro,
  etc). This causes the drawing FPS to drop to 30 FPS while logic is still
  kept at 60, and it's pretty evident that this can cause some issues with
  areas of the screen that don't clear/update frequently.

S'about it for now.
-------------------------------------------------------------------------------
P#80622 2020-08-11 07:36

[ :: Read More :: ]

Cart #wip_ma_20200807-0 | 2020-08-07 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
3

No gameplay yet, but the main menu and stuff looks
pretty much complete for now.
You can access the cheat menu with cheat code
"< > < > O X O X" when the "MR.GOOBER" screen comes up.
There's no gameplay once the intro cutscene and dialogs play.

I'm really superstitious about showing off my work to people prematurely
because it could chance me not finishing this, but I felt like doing it
because I thought it looked cool.

I went for a 4-color style game with changeable palettes in the options
menu. I want to not use the START menu because it breaks immersion.

I'm already halfway at the token limit so I'm going to need to find some
optimizations in the code later on, I'm sure. I'm already out of sound
space, and I was really hoping to make more music for the game.

Anyway, hope you all like it.

  • Goober
P#80445 2020-08-07 07:29 ( Edited 2020-08-07 07:30)